package com.blog4j.article.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.blog4j.api.client.FeignUser;
import com.blog4j.api.vo.UserInfoVo;
import com.blog4j.article.entity.ArticleEntity;
import com.blog4j.article.entity.CommentEntity;
import com.blog4j.article.mapper.ArticleMapper;
import com.blog4j.article.mapper.CommentMapper;
import com.blog4j.article.model.Comment;
import com.blog4j.article.model.CommentUser;
import com.blog4j.article.service.CommentService;
import com.blog4j.article.vo.req.CommentReqVo;
import com.blog4j.article.vo.req.SendCommentReqVo;
import com.blog4j.common.enums.ErrorEnum;
import com.blog4j.common.enums.YesOrNoEnum;
import com.blog4j.common.exception.Blog4jException;
import com.blog4j.common.utils.CommonUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author 98k灬
 * @version v1.0.0
 * @Description : 功能描述
 * @Create on : 2024/7/28 20:54
 **/
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class CommentServiceImpl extends ServiceImpl<CommentMapper, CommentEntity>
        implements CommentService {
    private final ArticleMapper articleMapper;
    private final FeignUser feignUser;

    /**
     * 获取文章评论列表
     *
     * @param reqVo 请求信息
     * @return 评论列表
     */
    @Override
    public PageInfo<Comment> commentList(CommentReqVo reqVo) {
        Integer pageSize = reqVo.getPageSize();
        Integer pageNo = reqVo.getPageNo();
        String articleId = reqVo.getArticleId();
        ArticleEntity article = articleMapper.selectById(articleId);
        if (Objects.isNull(article)) {
            throw new Blog4jException(ErrorEnum.ARTICLE_NOT_EXIST_ERROR);
        }

        LambdaQueryWrapper<CommentEntity> wrapper = new LambdaQueryWrapper<CommentEntity>()
                .eq(CommentEntity::getArticleId, articleId)
                .orderByDesc(CommentEntity::getCreateTime);
        Page<Object> page = PageHelper.startPage(pageNo, pageSize);
        List<CommentEntity> commentEntityList = this.baseMapper.selectList(wrapper);
        if (CollectionUtil.isEmpty(commentEntityList)) {
            return new PageInfo<>();
        }

        List<Comment> commentList = commentEntityList.stream().map(item -> {
            Comment comment = Comment.builder()
                    .parentId(item.getParentId())
                    .id(item.getCommentId())
                    .content(item.getContent())
                    .createDate(item.getCreateTime())
                    .build();

            String commentUserId = item.getCommentUserId();
            UserInfoVo commentUserInfo = feignUser.getUserInfoByUserId(commentUserId);
            CommentUser commentUser = CommentUser.builder()
                    .id(commentUserInfo.getId())
                    .nickName(commentUserInfo.getUserName())
                    .avatar(commentUserInfo.getAvatar())
                    .build();

            String targetUserId = item.getTargetUserId();
            CommentUser targetUser = new CommentUser();
            if (StringUtils.isNotBlank(targetUserId)) {
                UserInfoVo targetUserInfo = feignUser.getUserInfoByUserId(targetUserId);
                targetUser = CommentUser.builder()
                        .id(targetUserInfo.getId())
                        .nickName(targetUserInfo.getUserName())
                        .avatar(targetUserInfo.getAvatar())
                        .build();
            }
            comment.setCommentUser(commentUser).setTargetUser(targetUser);
            return comment;
        }).collect(Collectors.toList());

        List<Comment> list = new ArrayList<>();
        for (Comment entity : commentList) {
            if (Objects.equals(entity.getParentId(), 0)) {
                list.add(entity);
            }
        }

        for (Comment entity : list) {
            childrenMenu(commentList, entity);
        }

        PageInfo<Comment> pageInfo = new PageInfo<>(list);
        pageInfo.setTotal(page.getTotal());
        return pageInfo;
    }

    /**
     * 给文章评论
     *
     * @param reqVo 评论信息
     */
    @Override
    public void sendComment(SendCommentReqVo reqVo) {
        String content = reqVo.getContent();
        Integer parentId = reqVo.getParentId();
        String commentUserId = reqVo.getCommentUserId();
        Integer targetUserId = reqVo.getTargetUserId();
        String articleId = reqVo.getArticleId();

        UserInfoVo commentUser = feignUser.getUserInfoByUserId(commentUserId);
        if (Objects.isNull(commentUser)) {
            throw new Blog4jException(ErrorEnum.USER_NOT_EXIST_ERROR);
        }

        ArticleEntity article = articleMapper.selectById(articleId);
        if (Objects.isNull(article)) {
            throw new Blog4jException(ErrorEnum.ARTICLE_NOT_EXIST_ERROR);
        }

        if (Objects.equals(article.getAllowComment(), YesOrNoEnum.NO.getCode())) {
            throw new Blog4jException(ErrorEnum.APPROVE_NOT_ALLOW_COMMENT_ERROR);
        }

        if (Objects.equals(YesOrNoEnum.NO.getCode(), parentId)) {
            CommentEntity commentEntity = CommentEntity.builder()
                    .parentId(parentId)
                    .articleId(articleId)
                    .content(content)
                    .commentUserId(commentUserId)
                    .deleted(YesOrNoEnum.NO.getCode())
                    .createTime(CommonUtil.getCurrentDateTime())
                    .build();
            this.baseMapper.insert(commentEntity);
        } else {
            if (Objects.isNull(targetUserId)) {
                throw new Blog4jException(ErrorEnum.INVALID_PARAMETER_ERROR);
            }

            UserInfoVo targetUser = feignUser.getUserInfoById(targetUserId);
            if (Objects.isNull(targetUser)) {
                throw new Blog4jException(ErrorEnum.USER_NOT_EXIST_ERROR);
            }

            CommentEntity commentEntity = CommentEntity.builder()
                    .parentId(parentId)
                    .articleId(articleId)
                    .content(content)
                    .commentUserId(commentUserId)
                    .targetUserId(targetUser.getUserId())
                    .deleted(YesOrNoEnum.NO.getCode())
                    .createTime(CommonUtil.getCurrentDateTime())
                    .build();
            this.baseMapper.insert(commentEntity);
        }
    }

    private Comment childrenMenu(List<Comment> menuList, Comment menu) {
        List<Comment> children = new ArrayList<>();
        for (Comment m : menuList) {
            if (Objects.equals(m.getParentId(), menu.getId())) {
                children.add(childrenMenu(menuList, m));
            }
        }
        menu.setChildrenList(children);
        return menu;
    }
}
